package com.huike.clues.service.impl;

import com.huike.clues.service.ISysFileService;
import com.huike.common.config.MinioConfig;
import com.huike.common.core.domain.AjaxResult;
import com.huike.common.utils.uuid.UUID;
import io.minio.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

@Service
@Slf4j
public class SysFileServiceImpl implements ISysFileService {

    @Autowired
    MinioConfig minioConfig;

    /**
     * 文件上传至Minio
     * 使用try catch finally进行上传
     * finally里进行资源的回收
     */
    @Override
    public AjaxResult upload(MultipartFile file) {
        InputStream inputStream = null;
        //创建Minio的连接对象
        MinioClient minioClient = getClient();
        //1.准备 桶名
        String bucketName = minioConfig.getBucketName();
        try {
            inputStream = file.getInputStream();
            //判断 是否存在该bucketName
            boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());

            if (!exists) {
                //没有 就创建 该bucketName
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }

            //2.准备 上传文件的类型 contentType/pdf
            String contentType = minioConfig.getContentType();


            //3.准备 目录 为 桶名/yyyy-MM-dd/
            String fileUploadPath = new SimpleDateFormat(minioConfig.getDateFormat()).format(new Date());

            //4.准备 生成 随机文件名 UUIDxxx
            String originalFilename = file.getOriginalFilename();

            //TODO 文件名可能为null
            String fileName = UUID.randomUUID().toString().replace("-", "").substring(0, 6) + originalFilename.substring(originalFilename.lastIndexOf("."));


            //构建上传所需的信息 如 桶，文件名，文件流，文件类型等
            PutObjectArgs objectArgs = PutObjectArgs.builder()
                    .bucket(bucketName) //指定桶名
                    .object(fileUploadPath + fileName) //指定保存文件 路径+文件名
                    .stream(file.getInputStream(), file.getSize(), -1) //指定要写出的文件流
                    //.contentType(contentType) //指定文件的类型
                    .build();

            //执行 上传
            minioClient.putObject(objectArgs);

            //合同上传成功 保存合同到数据库中


            //构建返回结果集 返回生成的文件名
            //return AjaxResult.success("合同上传成功", fileName);
            AjaxResult success = AjaxResult.success();
            success.put("fileName","/"+bucketName+"/"+fileUploadPath + fileName);
            success.put("url","http://127.0.0.1:9000"+"/"+bucketName+"/"+fileUploadPath + fileName);
            return success;
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("上传失败");
        } finally {
            //防止内存泄漏
            if (inputStream != null) {
                try {
                    inputStream.close(); // 关闭流
                } catch (IOException e) {
                    log.debug("inputStream close IOException:" + e.getMessage());
                }
            }
        }
    }


    /**
     * 免费提供一个获取Minio连接的方法
     * 获取Minio连接
     *
     * @return
     */
    private MinioClient getClient() {

        MinioClient minioClient = MinioClient.builder()
                .endpoint("http://" + minioConfig.getEndpoint() + ":" + minioConfig.getPort())
                .credentials(minioConfig.getAccessKey(), minioConfig.getSecretKey())
                .build();

        return minioClient;
    }
}
